#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
模块名称: user.py
完整存储路径: backend/models/user.py
功能说明:
    定义用户表模型，存储用户的基本信息（如用户名、密码、角色、状态）。
    提供对用户账户的基本操作：创建、编辑、删除、查询等。
    
使用说明:
    通过 SQLAlchemy ORM 对用户数据进行 CRUD 操作。提供 API 接口支持。
"""
from datetime import datetime
from backend.infrastructure.database import db
from werkzeug.security import generate_password_hash, check_password_hash

class User(db.Model):
    __tablename__ = "users"

    id = db.Column(db.Integer, primary_key=True, autoincrement=True)
    username = db.Column(db.String(50), unique=True, nullable=False, index=True, comment="用户名")
    password_hash = db.Column(db.String(255), nullable=False, comment="密码（加密存储）")
    # 移除单角色字段，改为多对多
    roles = db.relationship('Role', secondary='user_roles', backref=db.backref('users', lazy='dynamic'))
    status = db.Column(db.String(20), nullable=False, default="active", comment="账户状态（active/inactive）")
    last_login = db.Column(db.DateTime, nullable=True, comment="最后登录时间")
    created_at = db.Column(db.DateTime, default=datetime.utcnow, comment="创建时间")
    # 用户中心常用字段
    real_name = db.Column(db.String(50), nullable=True, comment="真实姓名")
    mobile = db.Column(db.String(20), nullable=True, comment="手机号")
    email = db.Column(db.String(100), nullable=True, comment="邮箱")
    gender = db.Column(db.String(10), nullable=True, comment="性别")
    department = db.Column(db.String(100), nullable=True, comment="部门")
    position = db.Column(db.String(100), nullable=True, comment="岗位")
    remark = db.Column(db.String(255), nullable=True, comment="备注")
    # ========== 资料扩展追加字段（保持向后兼容：不修改原字段、不删除，仅新增） ==========
    birth_date = db.Column(db.Date, nullable=True, comment="出生日期（个人用户/家长可选填写，避免与学生birthday混淆）")
    address = db.Column(db.String(255), nullable=True, comment="联系地址（家长/工作人员可维护）")
    
    # 小程序相关字段
    openid = db.Column(db.String(100), nullable=True, unique=True, comment="微信openid")
    user_type = db.Column(db.String(20), default='web', comment="用户类型：web-网页用户,miniprogram-小程序用户")
    bind_status = db.Column(db.String(20), default='unbound', comment="绑定状态：unbound-未绑定,bound-已绑定")
    student_id = db.Column(db.Integer, db.ForeignKey('students.id'), nullable=True, comment="绑定的学生ID")
    nickname = db.Column(db.String(50), nullable=True, comment="昵称")
    avatar = db.Column(db.String(500), nullable=True, comment="头像URL")
    
    # 社交分享关联关系
    social_shares = db.relationship('SocialShare', back_populates='user', cascade='all, delete-orphan')
    
    # 用户关注关系
    followings = db.relationship('UserFollow', foreign_keys='UserFollow.follower_id', back_populates='follower')
    followers = db.relationship('UserFollow', foreign_keys='UserFollow.following_id', back_populates='following')
    
    # 通知相关关系 - 明确指定外键避免SQLAlchemy冲突
    notifications = db.relationship('Notification', foreign_keys='Notification.user_id', back_populates='user', cascade='all, delete-orphan')
    created_notifications = db.relationship('Notification', foreign_keys='Notification.created_by', back_populates='creator')
    notification_settings = db.relationship('NotificationSetting', back_populates='user', cascade='all, delete-orphan')
    
    # 反馈相关关系
    feedbacks = db.relationship('Feedback', foreign_keys='Feedback.user_id', back_populates='user', cascade='all, delete-orphan')

    @property
    def name(self):
        """兼容性属性，返回用户的显示名称"""
        return self.real_name or self.nickname or self.username

    @property
    def password(self):
        raise AttributeError('password is not a readable attribute')

    @password.setter
    def password(self, password):
        self.password_hash = generate_password_hash(password)

    def verify_password(self, password):
        return check_password_hash(self.password_hash, password)

    def to_dict(self):
        # 如果用户绑定了学生，获取学生的教育ID
        education_id = None
        if self.student_id:
            from backend.models.student import Student
            student = Student.query.get(self.student_id)
            if student:
                education_id = student.education_id
        
        return {
            "id": self.id,
            "username": self.username,
            "roles": [role.name for role in self.roles],
            "status": self.status,
            "last_login": self.last_login.isoformat() if self.last_login else None,
            "created_at": self.created_at.isoformat() if self.created_at else None,
            "real_name": self.real_name,
            "mobile": self.mobile,
            "email": self.email,
            "gender": self.gender,
            "department": self.department,
            "position": self.position,
            "remark": self.remark,
            "birth_date": self.birth_date.isoformat() if getattr(self, 'birth_date', None) else None,
            "address": self.address,
            # 小程序相关字段
            "openid": self.openid,
            "user_type": self.user_type,
            "bind_status": self.bind_status,
            "student_id": self.student_id,  # 保留用于内部逻辑
            "education_id": education_id,   # 添加教育ID用于前端显示
            "nickname": self.nickname,
            "avatar": self.avatar,
            # 微信绑定状态
            "wechat_bound": bool(self.openid),  # 根据openid判断是否绑定微信
            "wechat_id": self.openid  # 微信ID就是openid
        }

    def __repr__(self):
        return f"<User {self.username}>"

class UserRole:
    VIEWER = 'viewer'           # 查看权限
    OPERATOR = 'operator'       # 录入权限
    ADMIN = 'admin'            # 管理权限
    SUPER_ADMIN = 'super_admin' # 超级管理员

class ImportPermission:
    FILL_EMPTY = 'fill_empty'      # 填充空字段
    OVERRIDE_EXISTING = 'override_existing'  # 覆盖已有数据
    MODIFY_BASIC_INFO = 'modify_basic_info'  # 修改基本信息